/*

Summary:
Template wrapper functions for CRT string functions.

Remark:
None.

Version:
0.1.0

LastUpdatedDate:
2012-12-04

CreatedDate:
2012-09-20

*/

#pragma once

#include <string.h>



namespace Zaf {
namespace String {


template<typename CharType>
unsigned int StrLen(const CharType* str);

template<>
inline unsigned int StrLen<char>(const char* str) {
	return strlen(str);
}

template<>
inline unsigned int StrLen<wchar_t>(const wchar_t* str) {
	return wcslen(str);
}



template<typename CharType>
int StrCmp(const CharType* str1, const CharType* str2);

template<>
inline int StrCmp<char>(const char* str1, const char* str2) {
	return strcmp(str1, str2);
}

template<>
inline int StrCmp<wchar_t>(const wchar_t* str1, const wchar_t* str2) {
	return wcscmp(str1, str2);
}



template<typename CharType>
int StrICmp(const CharType* str1, const CharType* str2);

template<>
inline int StrICmp<char>(const char* str1, const char* str2) {
	return _stricmp(str1, str2);
}

template<>
inline int StrICmp<wchar_t>(const wchar_t* str1, const wchar_t* str2) {
	return _wcsicmp(str1, str2);
}



template<typename CharType>
int StrNCmp(const CharType* str1, const CharType* str2, unsigned int count);

template<>
inline int StrNCmp<char>(const char* str1, const char* str2, unsigned int count) {
	return strncmp(str1, str2, count);
}

template<>
inline int StrNCmp<wchar_t>(const wchar_t* str1, const wchar_t* str2, unsigned int count) {
	return wcsncmp(str1, str2, count);
}



template<typename CharType>
int StrNICmp(const CharType* str1, const CharType* str2, unsigned int count);

template<>
inline int StrNICmp<char>(const char* str1, const char* str2, unsigned int count) {
	return _strnicmp(str1, str2, count);
}

template<>
inline int StrNICmp<wchar_t>(const wchar_t* str1, const wchar_t* str2, unsigned int count) {
	return _wcsnicmp(str1, str2, count);
}



template<typename CharType>
const CharType* StrChr(const CharType* str, CharType ch);

template<>
inline const char* StrChr<char>(const char* str, char ch) {
	return strchr(str, ch);
}

template<>
inline const wchar_t* StrChr<wchar_t>(const wchar_t* str, wchar_t ch) {
	return wcschr(str, ch);
}

template<typename CharType>
CharType* StrChr(CharType* str, CharType ch);

template<>
inline char* StrChr<char>(char* str, char ch) {
	return strchr(str, ch);
}

template<>
inline wchar_t* StrChr<wchar_t>(wchar_t* str, wchar_t ch) {
	return wcschr(str, ch);
}



template<typename CharType>
const CharType* StrRChr(const CharType* str, CharType ch);

template<>
inline const char* StrRChr<char>(const char* str, char ch) {
	return strrchr(str, ch);
}

template<>
inline const wchar_t* StrRChr<wchar_t>(const wchar_t* str, wchar_t ch) {
	return wcsrchr(str, ch);
}

template<typename CharType>
CharType* StrRChr(CharType* str, CharType ch);

template<>
inline char* StrRChr<char>(char* str, char ch) {
	return strrchr(str, ch);
}

template<>
inline wchar_t* StrRChr<wchar_t>(wchar_t* str, wchar_t ch) {
	return wcsrchr(str, ch);
}



template<typename CharType>
const CharType* StrStr(const CharType* str, const CharType* searchStr);

template<>
inline const char* StrStr<char>(const char* str, const char* searchStr) {
	return strstr(str, searchStr);
}

template<>
inline const wchar_t* StrStr<wchar_t>(const wchar_t* str, const wchar_t* searchStr) {
	return wcsstr(str, searchStr);
}



template<typename CharType>
CharType* StrStr(CharType* str, const CharType* searchStr);

template<>
inline char* StrStr<char>(char* str, const char* searchStr) {
	return strstr(str, searchStr);
}

template<>
inline wchar_t* StrStr<wchar_t>(wchar_t* str, const wchar_t* searchStr) {
	return wcsstr(str, searchStr);
}



template<typename CharType>
long StrToLong(const CharType* str, CharType** endPtr, int radix);

template<>
inline long StrToLong<char>(const char* str, char** endPtr, int radix) {
	return strtol(str, endPtr, radix);
}

template<>
inline long StrToLong<wchar_t>(const wchar_t* str, wchar_t** endPtr, int radix) {
	return wcstol(str, endPtr, radix);
}



template<typename CharType>
unsigned long StrToULong(const CharType* str, CharType** endPtr, int radix);

template<>
inline unsigned long StrToULong<char>(const char* str, char** endPtr, int radix) {
	return strtoul(str, endPtr, radix);
}

template<>
inline unsigned long StrToULong<wchar_t>(const wchar_t* str, wchar_t** endPtr, int radix) {
	return wcstoul(str, endPtr, radix);
}



template<typename CharType>
long long StrToLLong(const CharType* str, CharType** endPtr, int radix);

template<>
inline long long StrToLLong<char>(const char* str, char** endPtr, int radix) {
	return _strtoi64(str, endPtr, radix);
}

template<>
inline long long StrToLLong<wchar_t>(const wchar_t* str, wchar_t** endPtr, int radix) {
	return _wcstoi64(str, endPtr, radix);
}



template<typename CharType>
unsigned long long StrToULLong(const CharType* str, CharType** endPtr, int radix);

template<>
inline unsigned long long StrToULLong<char>(const char* str, char** endPtr, int radix) {
	return _strtoui64(str, endPtr, radix);
}

template<>
inline unsigned long long StrToULLong<wchar_t>(const wchar_t* str, wchar_t** endPtr, int radix) {
	return _wcstoui64(str, endPtr, radix);
}



template<typename CharType>
errno_t LongToStr(long value, CharType* str, size_t sizeOfstr, int radix);

template<>
inline errno_t LongToStr<char>(long value, char* str, size_t sizeOfstr, int radix) {
	return _ltoa_s(value, str, sizeOfstr, radix);
}

template<>
inline errno_t LongToStr<wchar_t>(long value, wchar_t* str, size_t sizeOfstr, int radix) {
	return _ltow_s(value, str, sizeOfstr, radix);
}



template<typename CharType>
errno_t ULongToStr(unsigned long value, CharType* str, size_t sizeOfstr, int radix);

template<>
inline errno_t ULongToStr<char>(unsigned long value, char* str, size_t sizeOfstr, int radix) {
	return _ultoa_s(value, str, sizeOfstr, radix);
}

template<>
inline errno_t ULongToStr<wchar_t>(unsigned long value, wchar_t* str, size_t sizeOfstr, int radix) {
	return _ultow_s(value, str, sizeOfstr, radix);
}



template<typename CharType>
errno_t LLongToStr(long long value, CharType* str, size_t sizeOfstr, int radix);

template<>
inline errno_t LLongToStr<char>(long long value, char* str, size_t sizeOfstr, int radix) {
	return _i64toa_s(value, str, sizeOfstr, radix);
}

template<>
inline errno_t LLongToStr<wchar_t>(long long value, wchar_t* str, size_t sizeOfstr, int radix) {
	return _i64tow_s(value, str, sizeOfstr, radix);
}



template<typename CharType>
errno_t ULLongToStr(unsigned long long value, CharType* str, size_t sizeOfstr, int radix);

template<>
inline errno_t ULLongToStr<char>(unsigned long long value, char* str, size_t sizeOfstr, int radix) {
	return _ui64toa_s(value, str, sizeOfstr, radix);
}

template<>
inline errno_t ULLongToStr<wchar_t>(unsigned long long value, wchar_t* str, size_t sizeOfstr, int radix) {
	return _ui64tow_s(value, str, sizeOfstr, radix);
}



template<typename CharType>
int IsSpace(CharType ch);

template<>
inline int IsSpace<char>(char ch) {
	return isspace(ch);
}

template<>
inline int IsSpace<wchar_t>(wchar_t ch) {
	return iswspace(ch);
}

}
}